﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ESpace
{
    public partial class FormEditValue : Form
    {
        bool bOk = false;
        ValueTp Tp = ValueTp.String;
        int valInt, minIVal, maxIVal;
        double valDouble, minDVal, maxDVal;
        string valString;
        enum ValueTp { String, StringNotEmpty, Int, Float}
        Object[] ExVal = null;
        String ExMess = "";

        public void SetWidth(int w)
        {
            if (w < 1) return;
            MinimumSize = new Size(30, Height);
            MaximumSize = new Size(3000, Height);
            Width = w;
            txbValue.Width = w; MinimumSize = txbValue.Size; 
            MaximumSize = txbValue.Size;
        }
        /// <summary>заголовок</summary>
        public String Caption = "";
        /// <summary>открывать по позиции курсора</summary>
        public bool PosByCursor = true;
        /// <summary>
        /// установка значений, которые нельзя вводить.
        /// ExMess - сообщение, если введено значение из списка ExVal
        /// </summary>
        public void SetExceptValues(Object[] ExVal, String ExMess)
        {
            this.ExVal = ExVal;
            this.ExMess = ExMess;
        }
        public bool TakeRegister = false;

        /// <summary>результирующее значение</summary>
        public Object Value 
        { 
            get 
            {
                if (Tp == ValueTp.String || Tp == ValueTp.StringNotEmpty) return valString;
                if (Tp == ValueTp.Int) return valInt;
                if (Tp == ValueTp.Float) return valDouble;
                return null;
            } 
        }

        public FormEditValue()
        {
            InitializeComponent();
            MinimumSize = txbValue.Size;
            MaximumSize = txbValue.Size;
        }

        public void SetParams(String Caption, int Wdth, Object[] ExVal, String ExMess)
        {
            this.Caption = Caption;
            SetWidth(Wdth);
            this.ExVal = ExVal;
            this.ExMess = ExMess;
            PosByCursor = true;
        }

        public void SetParams(String Caption, int Wdth, Object[] ExVal, String ExMess, int Top, int Left)
        {
            this.Caption = Caption;
            SetWidth(Wdth);
            this.ExVal = ExVal;
            this.ExMess = ExMess;
            PosByCursor = false;
            this.Top = Top;
            this.Left = Left;
        }

        public bool ShowDialog(String InitialValue, bool NotNull)
        {
            valString = InitialValue;
            txbValue.Text = InitialValue;
            this.Tp = NotNull ? ValueTp.StringNotEmpty : ValueTp.String;
            ShowDlg();
            return bOk;
        }

        public bool ShowDialog(int InitialValue, bool EmptyValue) { return ShowDialog(InitialValue, EmptyValue, int.MinValue, int.MaxValue); }
        public bool ShowDialog(int InitialValue, bool EmptyValue, int minValue, int maxValue)
        {
            valInt = InitialValue;
            minIVal = minValue;
            maxIVal = maxValue;
            this.Tp = ValueTp.Int;
            txbValue.Text = EmptyValue ? "" : InitialValue.ToString();
            ShowDlg();
            return bOk;
        }

        public bool ShowDialog(double InitialValue, bool EmptyValue) { return ShowDialog(InitialValue, EmptyValue, double.MinValue, double.MaxValue); }
        public bool ShowDialog(double InitialValue, bool EmptyValue, double minValue, double maxValue)
        {
            valDouble = InitialValue;
            minDVal = minValue;
            maxDVal = maxValue;
            this.Tp = ValueTp.Float;
            txbValue.Text = EmptyValue ? "" : InitialValue.ToString();
            ShowDlg();
            return bOk;
        }

        void ShowDlg()
        {
            if (Caption != "")
            {
                MinimumSize = new Size(txbValue.Width, txbValue.Height + 15);
                MaximumSize = new Size(txbValue.Width, txbValue.Height + 15);
                label1.Visible = true;
                label1.Text = Caption;
            }
            else
            {
                MinimumSize = txbValue.Size;
                MaximumSize = txbValue.Size;
                label1.Visible = false;
            }

            if (PosByCursor) 
            {
                Top = Cursor.Position.Y - txbValue.Height / 2; 
                Left = Cursor.Position.X - txbValue.Width / 2;
                if (Top < 0) Top = 0;
                if (Left < 0) Left = 0;
            }
            bOk = false;
            ShowDialog();
        }

        private void txbValue_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                e.IsInputKey = false;
                // проверки
                String val = txbValue.Text.Trim();
                valString = val;
                if (Tp == ValueTp.StringNotEmpty && val == "")
                {
                    MessageBox.Show("Поле не может быть пустым");
                    return;
                }
                if (Tp == ValueTp.Int)
                {
                    if (!int.TryParse(val, out valInt))
                    {
                        MessageBox.Show("Значение не является целым числом");
                        return;
                    }
                    if (valInt < minIVal || valInt > maxIVal)
                    {
                        MessageBox.Show("Значение должно быть в диапазоне от " + minIVal.ToString() + " до " + maxIVal.ToString() + " включительно");
                        return;
                    }
                }
                if (Tp == ValueTp.Float)
                {
                    if (!double.TryParse(val, out valDouble))
                    {
                        MessageBox.Show("Значение не является числом");
                        return;
                    }
                    if (valDouble < minDVal || valDouble > maxDVal)
                    {
                        MessageBox.Show("Значение должно быть в диапазоне от " + minDVal.ToString() + " до " + maxDVal.ToString() + " включительно");
                        return;
                    }
                }
                
                // недопустимые значения
                if (!TakeRegister && Tp == ValueTp.String || Tp == ValueTp.StringNotEmpty) val = val.ToUpper();
                if (ExVal != null)
                { 
                    bool bExist = false;
                    for (int i = 0; i < ExVal.Length; i++)
                    {
                        if (Tp == ValueTp.String || Tp == ValueTp.StringNotEmpty)
                        {
                            String v = (String)ExVal[i];
                            if (!TakeRegister) v = v.ToUpper();
                            if (v == val)
                            {
                                bExist = true;
                                break;
                            }
                        }
                        if (Tp == ValueTp.Int)
                        {
                            int v = (int)ExVal[i];
                            if (v == valInt)
                            {
                                bExist = true;
                                break;
                            }
                        }
                        if (Tp == ValueTp.Float)
                        {
                            double v = (double)ExVal[i];
                            if (v == valDouble)
                            {
                                bExist = true;
                                break;
                            }
                        }
                    }
                    if (bExist)
                    {
                        MessageBox.Show(ExMess);
                        return;
                    }
                }
                
                bOk = true;
                Close();
            }

            if (e.KeyCode == Keys.Escape)
            {
                e.IsInputKey = false;
                Close();
            }
        }

    }
}
